package at.falb.games.alcatraz.api.client;

import java.awt.event.ActionEvent;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import at.falb.games.alcatraz.api.common.IGameConstants;
import at.falb.games.alcatraz.api.common.PlayerUnit;

public class Login extends JFrame implements IGameConstants {
    
	private static final long serialVersionUID = 49634636405293190L;

	private static Logger logger = Logger.getLogger(Login.class.getName());

	private ClientServerImpl serverInstance = null;
	private PlayerUnit player = null;

    private javax.swing.JButton btnLogin;
    private javax.swing.JButton btnLogout;
    private javax.swing.JButton btnStart;
    private javax.swing.JComboBox cbLoginServer;
    private javax.swing.JLabel lbPlayerName;
    private javax.swing.JLabel lbServerName;
    private javax.swing.JPanel panelInputParameter;
    private javax.swing.JTextField tfPlayerName;

    public Login(String[] servers) {

    	initComponents(servers);
    	try {
            javax.swing.UIManager.LookAndFeelInfo[] installedLookAndFeels=javax.swing.UIManager.getInstalledLookAndFeels();
            for (int idx=0; idx<installedLookAndFeels.length; idx++)
                if ("Nimbus".equals(installedLookAndFeels[idx].getName())) {
                    javax.swing.UIManager.setLookAndFeel(installedLookAndFeels[idx].getClassName());
                    break;
                }
        } catch (ClassNotFoundException exc) {
        	logger.log(Level.SEVERE, START_FAILED, exc);
        } catch (InstantiationException exc) {
        	logger.log(Level.SEVERE, START_FAILED, exc);
        } catch (IllegalAccessException exc) {
        	logger.log(Level.SEVERE, START_FAILED, exc);
        } catch (javax.swing.UnsupportedLookAndFeelException exc) {
        	logger.log(Level.SEVERE, START_FAILED, exc);
        }
        setVisible(true);
    }

    private void initComponents(String[] servers) {

        panelInputParameter = new javax.swing.JPanel();
        lbPlayerName = new javax.swing.JLabel();
        tfPlayerName = new javax.swing.JTextField();
        lbServerName = new javax.swing.JLabel();
        cbLoginServer = new javax.swing.JComboBox();
        
        btnLogin = new javax.swing.JButton();
        btnLogin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	btnLoginAction(evt);
            }
        });
        btnLogout = new javax.swing.JButton();
        btnLogout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	btnLogoutAction(evt);
            }
        });
        btnStart = new javax.swing.JButton();
        btnStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	btnStartAction(evt);
            }
        });

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Alcatraz Login");
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setLocationByPlatform(true);

        panelInputParameter.setBorder(javax.swing.BorderFactory.createTitledBorder("Willkommen bei Alcatraz Spiel"));

        lbPlayerName.setText("Spielername:");

        lbServerName.setText("Servername:");

        tfPlayerName.setText("Spieler");

        btnLogin.setText("Login");

        cbLoginServer.setModel(new javax.swing.DefaultComboBoxModel(servers));
        cbLoginServer.setEnabled(false);

        org.jdesktop.layout.GroupLayout panelInputParameterLayout = new org.jdesktop.layout.GroupLayout(panelInputParameter);
        panelInputParameter.setLayout(panelInputParameterLayout);
        panelInputParameterLayout.setHorizontalGroup(
            panelInputParameterLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
            .add(panelInputParameterLayout.createSequentialGroup()
                .addContainerGap()
                .add(panelInputParameterLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(panelInputParameterLayout.createSequentialGroup()
                        .add(lbServerName)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(cbLoginServer, 0, 376, Short.MAX_VALUE))
                    .add(panelInputParameterLayout.createSequentialGroup()
                        .add(lbPlayerName)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(tfPlayerName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 293, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 26, Short.MAX_VALUE)
                        .add(btnLogin)))
                .addContainerGap())
        );
        panelInputParameterLayout.setVerticalGroup(
            panelInputParameterLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, panelInputParameterLayout.createSequentialGroup()
                .addContainerGap(13, Short.MAX_VALUE)
                .add(panelInputParameterLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lbPlayerName)
                    .add(tfPlayerName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(btnLogin))
                .add(14, 14, 14)
                .add(panelInputParameterLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(cbLoginServer, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lbServerName))
                .addContainerGap())
        );

        btnLogout.setText("Logout");
        btnLogout.setEnabled(false);
        btnLogout.setFocusable(false);

        btnStart.setText("Start");
        btnStart.setEnabled(false);
        btnStart.setFocusable(false);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(btnStart)
                        .add(31, 31, 31)
                        .add(btnLogout)
                        .add(20, 20, 20))
                    .add(layout.createSequentialGroup()
                        .add(panelInputParameter, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap())))
        );

        layout.linkSize(new java.awt.Component[] {btnLogout, btnStart}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(23, 23, 23)
                .add(panelInputParameter, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 27, Short.MAX_VALUE)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btnStart)
                    .add(btnLogout))
                .add(24, 24, 24))
        );

        pack();
    }

    private ClientServerImpl getClientServerInstanze(String host) throws RemoteException, UnexpectedException  {
    	if (serverInstance == null) {
    		if (host == null || host.trim().isEmpty())
    			throw new UnexpectedException(UNDEFINED_SERVER);
    		serverInstance = new ClientServerImpl(host);
    	}
    	return serverInstance;
    }

    private ClientServerImpl getClientServerInstanze() throws RemoteException, UnexpectedException  {
    	return getClientServerInstanze(null);
    }

    private void setButtonsEnabled(boolean loginEnabled, boolean logoutEnabled, boolean startEnabled) {
    	tfPlayerName.setEnabled(loginEnabled);
    	btnLogin.setEnabled(loginEnabled);	
    	btnLogout.setEnabled(logoutEnabled);		
    	btnStart.setEnabled(startEnabled);    	
    }

    protected void btnLoginAction(java.awt.event.ActionEvent evt) {
    	try {
			player = getClientServerInstanze(
						cbLoginServer.getSelectedItem().toString()).
							playerLogin(tfPlayerName.getText());
	    	setButtonsEnabled(false, true, true);
	    	cbLoginServer.setEnabled(false);
		} catch (UnexpectedException exc) {
        	logger.log(Level.CONFIG, exc.getMessage(), exc);
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), LOGIN_TITLE_ERROR, JOptionPane.OK_OPTION);
		} catch (RemoteException exc) {
        	logger.log(Level.WARNING, START_FAILED, exc);
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), LOGIN_TITLE_INFO, JOptionPane.OK_OPTION);
    	}
    }

    protected void btnLogoutAction(ActionEvent evt) {
		try {
			if (getClientServerInstanze().playerLogout(player)) {
				player = null;
				setButtonsEnabled(true, false, false);
			}
		} catch (UnexpectedException exc) {
        	logger.log(Level.CONFIG, exc.getMessage(), exc);
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), LOGIN_TITLE_ERROR, JOptionPane.OK_OPTION);
		} catch (RemoteException exc) {
        	logger.log(Level.WARNING, START_FAILED, exc);
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), LOGIN_TITLE_INFO, JOptionPane.OK_OPTION);
		}
	}

    protected void btnStartAction(ActionEvent evt) {
		try {
			if (getClientServerInstanze().startGame(player)) {
				List<PlayerUnit> players = getClientServerInstanze().getPlayer(player);
				GameClient game = new GameClient(players.size());
				game.startGame(player, players);
				this.dispose();
			} else {
                JOptionPane.showMessageDialog(this, INSUFFICIENT_PLAYERS, LOGIN_TITLE_INFO, JOptionPane.OK_OPTION);
			}
		} catch (UnexpectedException exc) {
        	logger.log(Level.CONFIG, exc.getMessage(), exc);
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), LOGIN_TITLE_ERROR, JOptionPane.OK_OPTION);
		} catch (RemoteException exc) {
        	logger.log(Level.WARNING, START_FAILED, exc);
            JOptionPane.showMessageDialog(this, exc.getLocalizedMessage(), LOGIN_TITLE_INFO, JOptionPane.OK_OPTION);
		}
	}
}
